As it is written, calling factorial( -1 )
would grow the activation chain without limit.
int factorial( int N ) { if ( N == 0 ) return 1; else return N * factorial( N-1 ) ; }
The first activation would activate factorial( -2 )
,
which would activate factorial( -3 )
, and so on.
The base case (of N == 0
) would never be reached.
Eventually the computer system would run out of resources,
and the program would stop running.
Defensive programming is when a programmer anticipates
problems and writes code to deal with them.
To avoid the disaster a negative parameter would cause,
sometimes factorial()
is written like this:
int factorial( int N ) { if ( N <= 0 ) return 1; else return N * factorial( N-1 ) ; }
But, according to the math-like definition, this is not correct.
The value of factorial( -1 )
is undefined,
not equal to one.
Potentially, returning an incorrect value and continuing on as if nothing is
wrong might cause a greater disaster than stopping the computer system.
Sometimes the method is written to throw an exception when an illegal argument is detected. (Exceptions are discussed in chapter 80.) But this adds complication since now the caller must deal with a possible exception.
Perhaps the best idea is to write factorial()
so that it follows the math-like definition exactly.
Make it the responsibility of the caller to
make sure that the argument is within range.
Here is another idea: why not have factorial()
use
the absolute value of its argument to be sure that it is positive?